---
id: query
sidebar_position: 2
hide_table_of_contents: true
title: 查询
description: 查询是执行带有结果的SQL语句并获取结果集的操作。
---
import TOCInline from '@theme/TOCInline';

查询是执行带有结果的SQL语句并获取结果集的操作。

:::info
- dbVisitor 支持多种参数传递方式，为了便于理解下面执行 SQL 的案例中选择常用的 **无参数**、**位置参数**、**名称参数** 三种。
- 想要了解更多参数传递内容请到 **[参数传递](../../args/about)** 页面查看。
:::

下面列出了一些常见用法：

<TOCInline toc={toc} />

## 查询结果集

有许多种方式都可以进行查询并获取结果集。下面列出几种常见的形式：

- 返回 [List/Map](../../result/for_map)
    ```java title='使用原始 SQL'
    List<Map<String, Object>> result = jdbc.queryForList("select * from users");
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    List<Map<String, Object>> result = jdbc.queryForList("select * from users where id > ?", args);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("id", 2);
    List<Map<String, Object>> result = jdbc.queryForList("select * from users where id > :id", args);
    ```
    :::info
    **queryForList** 查询返回的 **List** 结构中使用 **LinkedCaseInsensitiveMap** 或 **LinkedHashMap** 类型进行行数据的存储。
    - 更加详细信息请参考使用 List/Map 接收数据中的 **[结果集列名大小写敏感性](../../result/for_map#case)**。
    :::

- 使用 [RowMapper](../../result/for_mapper)
    ```java title='使用原始 SQL'
    RowMapper<User> rowMapper = ...
    List<User> result = jdbc.queryForList("select * from users", rowMapper);
    ```
    ```java title='使用位置参数'
    RowMapper<User> rowMapper = ...
    Object[] args = new Object[]{ 2 };
    List<User> result = jdbc.queryForList("select * from users where id > ?", args, rowMapper);
    ```
    ```java title='使用名称参数'
    RowMapper<User> rowMapper = ...
    Map<String, Object> args = CollectionUtils.asMap("id", 2);
    List<User> result = jdbc.queryForList("select * from users where id > :id", args, rowMapper);
    ```

- 使用 [对象映射](../../core/mapping/about) 或 [类型处理器](../../types/about)
    ```java title='使用原始 SQL'
    List<User> result = jdbc.queryForList("select * from users", User.class);
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    List<User> result = jdbc.queryForList("select * from users where id > ?", args, User.class);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("id", 2);
    List<User> result = jdbc.queryForList("select * from users where id > :id", args, User.class);
    ```

- 使用 [ResultSetExtractor](../../result/for_extractor)
    ```java title='使用原始 SQL'
    ResultSetExtractor<T> extractor = ...
    T result = jdbc.query("select * from users", extractor);
    ```
    ```java title='使用位置参数'
    ResultSetExtractor<T> extractor = ...
    T result = jdbc.query("select * from users where id > ?", args, extractor);
    ```
    ```java title='使用名称参数'
    ResultSetExtractor<T> extractor = ...
    T result = jdbc.query("select * from users where id > :id", args, extractor);
    ```

## 查询一行 {#row}

当查询结果预期只有一条记录时，可以通过下面几种形式的方法获取映射后的结果。

- 使用 [Map](../../result/for_map)
    ```java title='使用原始 SQL'
    Map<String, Object> user = jdbc.queryForMap("select * from users where name = 'Bob'");
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    Map<String, Object> user = jdbc.queryForMap("select * from users where name = ?", args);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("name", "Bob");
    Map<String, Object> user = jdbc.queryForMap("select * from users where name = :name", args);
    ```
    :::info
    **queryForMap** 查询结果会使用 **LinkedCaseInsensitiveMap** 或 **LinkedHashMap** 类型存储行数据。
    - 更加详细信息请参考 **[使用 List/Map 接收数据](../../result/for_map#case)**。
    :::
- 使用 [RowMapper](../../result/for_mapper)
    ```java title='使用原始 SQL'
    RowMapper<User> rowMapper = ...
    List<User> result = jdbc.queryForObject("select * from users where name = 'Bob'", rowMapper);
    ```
    ```java title='使用位置参数'
    RowMapper<User> rowMapper = ...
    Object[] args = new Object[]{ 2 };
    List<User> result = jdbc.queryForObject("select * from users where name = ?", args, rowMapper);
    ```
    ```java title='使用名称参数'
    RowMapper<User> rowMapper = ...
    Map<String, Object> args = CollectionUtils.asMap("name", "Bob");
    List<User> result = jdbc.queryForObject("select * from users where name = :name", args, rowMapper);
    ```
- 使用 [对象映射](../../core/mapping/about)
    ```java title='使用原始 SQL'
    List<User> result = jdbc.queryForObject("select * from users where name = 'Bob'", User.class);
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    List<User> result = jdbc.queryForObject("select * from users where name = ?", args, User.class);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("name", "Bob");
    List<User> result = jdbc.queryForObject("select * from users where name = :name", args, User.class);
    ```

## 查询单值 {#value}

当查询结果预期只是一个值时，可以通过下面几种形式的方式获取查询的值。

- **int** 类型
    ```java title='使用原始 SQL'
    int result = jdbc.queryForInt("select count(*) from users where age > 21");
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 21 };
    int result = jdbc.queryForInt("select count(*) from users where age > ?", args);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("age", 21);
    int result = jdbc.queryForInt("select count(*) from users where age > :age", args);
    ```
- **long** 类型
    ```java title='使用原始 SQL'
    int result = jdbc.queryForLong("select count(*) from users where age > 21");
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 21 };
    int result = jdbc.queryForLong("select count(*) from users where age > ?", args);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("age", 21);
    int result = jdbc.queryForLong("select count(*) from users where age > :age", args);
    ```
- **字符串** 类型
    ```java title='使用原始 SQL'
    String name = jdbc.queryForString("select name from users where id = 2", User.class);
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    String name = jdbc.queryForString("select name from users where id = ?", args, User.class);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("id", 2);
    String name = jdbc.queryForString("select name from users where id = :id", args, User.class);
    ```
- [类型处理器](../../types/about)
    ```java title='使用原始 SQL'
    LocalDateTime result = jdbc.queryForObject("select create_time from users where name = 'Bob'", LocalDateTime.class);
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    LocalDateTime result = jdbc.queryForObject("select create_time from users where name = ?", args, LocalDateTime.class);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("name", "Bob");
    LocalDateTime result = jdbc.queryForObject("select create_time from users where name = :name", args, LocalDateTime.class);
    ```

## 查询值列表 {#values}

值列表方式查询是指查询只返回一个列。被查询的列可以是 [TypeHandlerRegistry](../../types/handlers/about) 注册器中注册的类型。

- 使用方式
    ```java title='使用原始 SQL'
    List<String> result = jdbc.queryForList("select name from users", String.class);
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    List<String> result = jdbc.queryForList("select name from users where name = ?", args, String.class);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("name", "Bob");
    List<String> result = jdbc.queryForList("select name from users where id = :id", args, String.class);
    ```

## 查询键值对 {#pairs}

键值对是将查询到的结果集将第一个列和第二个列分别作为 Map 的 Key 和 Value 将整个结果集存储为一个 Map 类型。

- 使用方式
    ```java title='使用原始 SQL'
    Map<Long, String> userMap = jdbc.queryForPairs("select uid, name from user", Long.class, String.class);
    ```
    ```java title='使用位置参数'
    Object[] args = new Object[]{ 2 };
    Map<Long, String> userMap = jdbc.queryForPairs("select uid, name from user where id = ?", Long.class, String.class, args);
    ```
    ```java title='使用名称参数'
    Map<String, Object> args = CollectionUtils.asMap("id", 2);
    Map<Long, String> userMap = jdbc.queryForPairs("select uid, name from user where id = :id", Long.class, String.class, args);
    ```

## 查询中处理数据

通过 [RowCallbackHandler](../../result/row_callback) 专注每一行的数据处理，而非获取结果集。

```java
RowCallbackHandler handler = new RowCallbackHandler() {
    @Override
    public void processRow(ResultSet rs, int rowNum) throws SQLException {
        ...
    }
};
```

```java title='使用原始 SQL'
RowCallbackHandler handler = ...
jdbc.query("select * from users", handler);
```

```java title='使用位置参数'
RowCallbackHandler handler = ...
Object[] args = new Object[]{ 2 };
jdbc.query("select * from users where id = ?", args, handler);
```

```java title='使用名称参数'
RowCallbackHandler handler = ...
Map<String, Object> args = CollectionUtils.asMap("name", "Bob");
jdbc.query("select * from users where name = :name", args, handler);
```
